package com.aqgj.Resource.service;

import com.aqgj.Resource.bean.Resource;
import com.aqgj.Resource.bean.ResourceVo;
import com.aqgj.Resource.dao.ResourceDao;
import com.aqgj.Role.dao.RoleDao;
import com.aqgj.RoleResource.bean.RoleResource;
import com.aqgj.RoleResource.dao.RoleResourceDao;
import com.aqgj.User.dao.UserDao;
import com.aqgj.UserRole.dao.UserRoleDao;
import com.aqgj.shiro.ShiroUser;
import com.ztc.util.exceptions.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


@Service("Resource")
public class ResourceManager{
    @Autowired
    private ResourceDao resourceDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserRoleDao userRoleDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private RoleResourceDao roleResourceDao;


    private List<Resource> getChild(String id, List<Resource> children){
        // 子菜单
        List<Resource> childList = new ArrayList<>();
        for (Resource resource : children) {
            // 遍历所有节点，将父菜单id与传过来的id比较
            if(resource.getPid()!=null && !"".equals(resource.getPid())){
                if (resource.getPid().equals(id)) {
                    childList.add(resource);
                }
            }
        }
        // 把子菜单的子菜单再循环一遍
        for (Resource resource : childList) {
            // 递归
            resource.setResourceList(getChild(resource.getId(), children));
        }
        // 递归退出条件
        if (childList.size() == 0) {
            return null;
        }
        return childList;
    }

    public List<Resource> selectAll() {
        List<Resource> resourceList = resourceDao.getAll("sort",true);
        List<Resource> resources = new ArrayList<>(5);
        for(Resource resource:resourceList){
            if(resource.getPid()==null || "".equals(resource.getPid())){
                resources.add(resource);
            }
        }
        for(Resource resource:resources){
            resource.setResourceList(getChild(resource.getId(), resourceList));
        }
        return resources;
    }

    private List<ResourceVo> getResourceVoChild(String id, List<ResourceVo> children,List<Object[]> roleResources){
        // 子菜单
        List<ResourceVo> childList = new ArrayList<>();
        for (ResourceVo resourceVo : children) {
            // 遍历所有节点，将父菜单id与传过来的id比较
            if(resourceVo.getPid()!=null && !"".equals(resourceVo.getPid())){
                if (resourceVo.getPid().equals(id)) {
                    if(roleResources.get(0)[0]!=null){
                        for (Object[] obj : roleResources) {
                            if (obj[0].toString().equals(resourceVo.getId()) && Integer.parseInt(obj[1].toString()) == 1) {
                                resourceVo.setChecked(true);
                            }
                        }
                    }
                    childList.add(resourceVo);
                }
            }
        }
        // 把子菜单的子菜单再循环一遍
        for (ResourceVo resourceVo : childList) {
            // 递归
            resourceVo.setChildren(getResourceVoChild(resourceVo.getId(), children,roleResources));
        }
        // 递归退出条件
        if (childList.size() == 0) {
            return null;
        }
        return childList;
    }


    public List<ResourceVo> selectResourceIdListByRoleId(String id) {
        // 获取所有的资源
        List<Resource> resourceList = resourceDao.getAll();
        List<ResourceVo> resourceVos = new ArrayList<>();
        if (resourceList == null) {
            return resourceVos;
        }
        for (Resource resource : resourceList) {
            ResourceVo resourceVo = new ResourceVo();
            resourceVo.setId(resource.getId());
            resourceVo.setPid(resource.getPid());
            resourceVo.setTitle(resource.getName());
            resourceVos.add(resourceVo);
        }
        List<ResourceVo> resourceVoList = new ArrayList<>(8);
        List<Object[]> roleResources = roleDao.selectResourceIdListByRoleId(id);
        for(ResourceVo resourceVo:resourceVos){
            if(resourceVo.getPid()==null || "".equals(resourceVo.getPid())){
                if(roleResources.get(0)[0]!=null){
                    for(Object[] obj:roleResources){
                        if(obj[0].toString().equals(resourceVo.getId()) && Integer.parseInt(obj[1].toString()) == 1){
                            resourceVo.setChecked(true);
                        }
                    }
                }
                resourceVoList.add(resourceVo);
            }
        }
        for(ResourceVo resourceVo:resourceVoList){
            resourceVo.setChildren(getResourceVoChild(resourceVo.getId(), resourceVos, roleResources));
        }
        return resourceVoList;
    }

    public List<Resource> selectTree(ShiroUser shiroUser) {
        List<Resource> trees = new ArrayList<Resource>();
        // shiro中缓存的用户角色
        Set<String> roles = shiroUser.getRoles();
        if (roles == null) {
            return trees;
        }
        // 如果有超级管理员权限
        if (roles.contains("admin")) {
            return selectAll();
        }
        // 普通用户
        List<String> roleIdList = userRoleDao.selectRoleIdListByUserId(shiroUser.getId());
        if (roleIdList == null || roleIdList.isEmpty()) {
            return trees;
        }

        List<Resource> resourceLists = userDao.selectResourceListByRoleIdList2(roleIdList);
        if (resourceLists == null) {
            return trees;
        }
        List<Resource> resourceOne = new ArrayList<>(8);
        for(Resource  resource:resourceLists){
            if(resource.getPid()==null || "".equals(resource.getPid())){
                resourceOne.add(resource);
            }
        }
        for(Resource resource:resourceOne){
            resource.setResourceList(getChild(resource.getId(), resourceLists));
        }
        return resourceOne;
    }

    public void deleteById(Serializable resourceId) {
        List<RoleResource> roleResourceList = roleResourceDao.findBy("resourceId",resourceId);
        if(roleResourceList.size()>0){
            throw new BusinessException("删除失败，该资源已被角色使用！");
        }
        Set<String> resourceIds = new HashSet<>();
        getChildrenResourceIds(resourceId,resourceIds);
        if(resourceIds.size()>0){
            for(String childrenResourceId:resourceIds){
                resourceDao.removeById(childrenResourceId);
            }
        }
        resourceDao.removeById(resourceId);
    }

    private void getChildrenResourceIds(Serializable resourceId,Set<String> resourceIds){
        List<Resource> resourceList = resourceDao.findBy("pid",resourceId);
        if(!resourceList.isEmpty()){
            for(Resource resource:resourceList){
                resourceIds.add(resource.getId());
                getChildrenResourceIds(resource.getId(),resourceIds);
            }
        }
    }

    /**
     *
     * @param resource
     * @return 1
     */

    public String insertResource(Resource resource){
//        保存时去除重复的urlName,修改时去除除当前条外其他重复的URLName，URLName为空时，可以保存
        if(resource.getUrlName()!=null &&resource.getUrlName()!=""){
            List<Resource> list= resourceDao.findBy("urlName",resource.getUrlName());
            if(list.size()==0){
                resourceDao.save(resource);
                return resource.getId();
            }else if(list.size()==1&&resource.getId()!=null&&resource.getId()!=""&&list.get(0).getId().equals(resource.getId())){
               Resource resource2=list.get(0);
               resource2.setCreateTime(resource.getCreateTime());
               resource2.setIcon(resource.getIcon());
               resource2.setName(resource.getName());
               resource2.setPid(resource.getPid());
               resource2.setResourceType(resource.getResourceType());
               resource2.setSort(resource.getSort());
               resource2.setStatus(resource.getStatus());
               resource2.setUrl(resource.getUrl());
               resource2.setUrlName(resource.getUrlName());
               resourceDao.save(resource2);
               return resource.getId();
           }else{return null;}
        }else{return null;}
    }
}
